package com.ssyx.payment.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.wxpay.sdk.WXPayUtil;
import com.ssyx.common.auth.AuthContextHolder;
import com.ssyx.enums.PaymentType;
import com.ssyx.model.order.PaymentInfo;
import com.ssyx.payment.service.PaymentInfoService;
import com.ssyx.payment.service.WeixinService;
import com.ssyx.payment.utils.ConstantPropertiesUtils;
import com.ssyx.payment.utils.HttpClient;
import com.ssyx.vo.user.UserLoginVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * ClassName:WeixinServiceImpl
 * Description:
 *
 * @Author kay
 * @Create 2024/5/24 16:59
 * @Version 1.0
 */
@Service
public class WeixinServiceImpl implements WeixinService {
    @Autowired
    private PaymentInfoService paymentInfoService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    //调用微信支付系统生成预付单
    @Override
    public Map<String, String> createJsapi(String orderNo) {

        //1.向payment_info支付记录表添加记录,目前支付状态:正在支付中
        PaymentInfo paymentInfo = paymentInfoService.getPaymentInfo(orderNo, PaymentType.WEIXIN);
        if(null == paymentInfo) {
            paymentInfo = paymentInfoService.savePaymentInfo(orderNo, PaymentType.WEIXIN);
        }
        //2.封装信息支付系统接口需要的参数
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("appid", ConstantPropertiesUtils.APPID);
        paramMap.put("mch_id", ConstantPropertiesUtils.PARTNER);
        paramMap.put("nonce_str", WXPayUtil.generateNonceStr());
        paramMap.put("body", paymentInfo.getSubject());
        paramMap.put("out_trade_no", paymentInfo.getOrderNo());
        int totalFee = paymentInfo.getTotalAmount().multiply(new BigDecimal(100)).intValue();
        paramMap.put("total_fee", String.valueOf(totalFee));
        paramMap.put("spbill_create_ip", "127.0.0.1");
        paramMap.put("notify_url", ConstantPropertiesUtils.NOTIFYURL);
        paramMap.put("trade_type", "JSAPI");
        //普通用户的openid无法得到微信支付系统接口,必须要用商户openid:oD7av4igt-00GI8PqsIlg5FROYnI,测试使用
        paramMap.put("openid", "oD7av4igt-00GI8PqsIlg5FROYnI");
        //从当前线程中获取登录信息对象UserLoginVo，里面封装有openid,或者从redis中得到登录信息对象,userId在支付信息中有
        ////String openid = AuthContextHolder.getUserLoginVo().getOpenId();
//        String loginKey = "user:ssyx:" + paymentInfo.getUserId();
//        String userLoginVoString = redisTemplate.opsForValue().get(loginKey);
//        UserLoginVo userLoginVo = JSON.parseObject(userLoginVoString, UserLoginVo.class);
//        String openid = userLoginVo.getOpenId();
//        if(null != userLoginVo && !StringUtils.isEmpty(openid)) {
//            paramMap.put("openid", openid);
//        } else {
//            paramMap.put("openid", "oD7av4igt-00GI8PqsIlg5FROYnI");
//        }

        //3.使用HttpClient调用微信支付系统接口
        HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");

        //client设置参数
        try {
            client.setXmlParam(WXPayUtil.generateSignedXml(paramMap, ConstantPropertiesUtils.PARTNERKEY));
            client.setHttps(true);
            client.post();

            //4.调用微信支付接口之后,返回结果
            String xml = client.getContent();
            Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);

            //5.封装需要的数据-包含预付单标识prepay_id
            Map<String, String> parameterMap = new HashMap<>();
            String prepayId = String.valueOf(resultMap.get("prepay_id"));
            String packages = "prepay_id=" + prepayId;
            parameterMap.put("appId", ConstantPropertiesUtils.APPID);
            parameterMap.put("nonceStr", resultMap.get("nonce_str"));
            parameterMap.put("package", packages);
            parameterMap.put("signType", "MD5");
            parameterMap.put("timeStamp", String.valueOf(new Date().getTime()));
            String sign = WXPayUtil.generateSignature(parameterMap, ConstantPropertiesUtils.PARTNERKEY);

            //6.返回结果
            Map<String, String> result = new HashMap<>();
            result.put("timeStamp", parameterMap.get("timeStamp"));
            result.put("nonceStr", parameterMap.get("nonceStr"));
            result.put("signType", "MD5");
            result.put("paySign", sign);
            result.put("package", packages);
            if(null != resultMap.get("result_code")) {
                //微信支付二维码2小时过期，可采取2小时未支付取消订单
                redisTemplate.opsForValue().set(orderNo+"weixianPayment", JSON.toJSONString(result), 120, TimeUnit.MINUTES);
            }
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return new HashMap<>();
        }
    }

    //1.调用微信支付接口,查询订单支付状态
    @Override
    public Map<String, String> queryPayStatus(String orderNo) {

            //1、封装参数
            Map<String,String> paramMap = new HashMap<>();
            paramMap.put("appid", ConstantPropertiesUtils.APPID);
            paramMap.put("mch_id", ConstantPropertiesUtils.PARTNER);
            paramMap.put("out_trade_no", orderNo);
            paramMap.put("nonce_str", WXPayUtil.generateNonceStr());

            //2、设置请求
        try {
            HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
            client.setXmlParam(WXPayUtil.generateSignedXml(paramMap, ConstantPropertiesUtils.PARTNERKEY));
            client.setHttps(true);
            client.post();
            //3、返回第三方的数据
            String xml = client.getContent();
            Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);
            return resultMap;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
